package com.jrfid.smartcabinet.demo.ui.login.finger

import android.app.Application
import androidx.databinding.ObservableField
import androidx.lifecycle.LifecycleOwner
import androidx.navigation.NavController
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ThreadUtils
import com.blankj.utilcode.util.ToastUtils
import com.jrfid.smartcabinet.demo.R
import com.jrfid.smartcabinet.demo.base.BaseViewModel
import com.jrfid.smartcabinet.demo.db.AppDatabase
import com.jrfid.smartcabinet.demo.model.CabinetConfigInfoModel
import com.jrfid.smartcabinet.demo.utils.Config
import com.xgzx.veinmanager.VeinApi

class LoginByFingerViewModel(application: Application, navController: NavController) : BaseViewModel(application, navController) {

    val tipsText = ObservableField("")
    private var devHandle: Long = -1
    private var loginThread: Thread? = null
    private var connectThread: Thread? = null

    override fun onResume(owner: LifecycleOwner) {
        super.onResume(owner)
        val list = Config.getCabinetList()
        if (list.isEmpty()) {
            tipsText.set(getString(R.string.text_config_cabinet_info))
            ToastUtils.showShort(getString(R.string.text_config_cabinet_info))
        } else {
            //获取主柜信息
            val info = list[0]
            connectThread = ConnectThread(info)
            connectThread?.start()
        }
    }

    override fun onPause(owner: LifecycleOwner) {
        super.onPause(owner)
        connectThread?.interrupt()
        loginThread?.interrupt()
        val code = VeinApi.FVCloseDev(devHandle)
        if (code == 0L) {
            LogUtils.dTag(TAG, "指静脉断开连接")
        }
    }

    private inner class ConnectThread(private var info: CabinetConfigInfoModel) : Thread() {
        override fun run() {
            super.run()
            try {
                if (!isInterrupted) {
                    devHandle = VeinApi.FVConnectDev("IP:${info.fingerIP.get()},PORT:${info.fingerPort.get()}", "00000000")
                    if (devHandle > 0) {
                        LogUtils.dTag(TAG, "连接成功")
                        loginThread = LoginThread()
                        loginThread?.start()
                    } else {
                        LogUtils.dTag(TAG, "连接失败")
                        ToastUtils.showLong(getString(R.string.text_connect_error))
                        tipsText.set(getString(R.string.text_connect_error))
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }


    private inner class LoginThread : Thread() {
        override fun run() {
            super.run()
            var searchHandle: Long? = null
            try {
                while (true) {
                    if (!isInterrupted) {
                        if (searchHandle == null) {
                            val fingerCharaList = AppDatabase.instance.getFingerInfoDao().queryAll()
                            searchHandle = VeinApi.FVCreateVeinLib(fingerCharaList.size.toLong())
                            if (searchHandle <= 0) {
                                LogUtils.dTag(TAG, "算法库创建失败：${searchHandle}")
                                searchHandle = null
                                sleep(1000)
                                continue
                            } else {
                                LogUtils.dTag(TAG, "算法库创建成功")
                                fingerCharaList.forEach {
                                    val userId = VeinApi.FVGetNullID(searchHandle)
                                    val code = VeinApi.FVImportVeinTemp(searchHandle, userId, it.finger)
                                    if (code == 0L) {
                                        LogUtils.dTag(TAG, "用户${userId}模板导入算法库成功")
                                    } else {
                                        LogUtils.dTag(TAG, "用户${userId}模板导入算法库失败${code}")
                                    }
                                }
                            }
                            //检测手指
                            val code = VeinApi.FVCheckFinger(devHandle)
                            if (code <= 0L) {
                                //无手指
                                tipsText.set(getString(R.string.text_login_by_finger_tips))
                            }
                        }
                        val sChara = VeinApi.FVGetVeinChara(devHandle, 6000) //通过指静脉设备采集特征，等待手指放入超时为6秒
                        if (sChara.length < 10) {
                            //获取失败
                            val error = sChara.toIntOrNull()
                            val text = if (error == -16) {
                                getString(R.string.text_finger_vein_not_support)
                            } else if (error == -11) {
                                getString(R.string.text_finger_vein_no_fingers)
                            } else if (error == -17) { //特征采集失败可以继续采集下一次
                                getString(R.string.text_finger_vein_incorrect)
                            } else {
                                getStringFormat(R.string.text_finger_vien_error, error ?: 0)
                            }
                            tipsText.set(text)
                            LogUtils.dTag(TAG, text)
                            sleep(1000)
                            continue
                        } else {
                            //获取成功
                            LogUtils.dTag(TAG, "特征值获取成功：${sChara}")
                            val userId = VeinApi.FVSearchUser(searchHandle, sChara, 2)
                            if (userId > 0) {
                                //识别成功
                                tipsText.set(getString(R.string.text_login_successfully))
                                ToastUtils.showLong(getString(R.string.text_login_successfully))
                                //登录成功
                                ThreadUtils.runOnUiThreadDelayed(Runnable {
                                    navController.navigate(R.id.action_loginFragment_to_homeFragment)
                                }, 1000)
                                break
                            } else {
                                //未注册
                                tipsText.set(getString(R.string.text_finger_unregister))
                                ToastUtils.showLong(getString(R.string.text_finger_unregister))
                            }
                        }
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                searchHandle?.let {
                    VeinApi.FVDestroyVeinLib(searchHandle)
                }
            }
        }
    }
}